package managers.dateManager.endFrozen.beginChange;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import junit.framework.TestCase;

import org.apache.log4j.Logger;
import org.tbjd.client.beans.Task;
import org.tbjd.client.constants.NotificationsConstants;
import org.tbjd.client.constants.TimeConstants;
import org.tbjd.client.exceptions.DateManagerException;
import org.tbjd.client.managers.TaskManager;
import org.tbjd.client.states.StateEndFrozenASAP;
import org.tbjd.client.states.StateEndFrozenSPEC;

import factories.TaskFactory;

/**
 * <p>
 * Test TaskManager's methods when BeginDate changed
 * </p>
 * <p>
 * <b>Case</b>
 * </p>
 * <p>
 * Multiple tasks in a phase with different ChainingMode,
 * </p>
 * <p>
 * When the BeginDate of the phase change, the tasks dates are updated
 * </p>
 * <p>
 * <b>Action</b>
 * </p>
 * <p>
 * BeginDate of the phase "f1" is changed
 * </p>
 * <p>
 * Expected
 * <ul>
 * <li>update BeginDate/EndDate of phase "f1"</li>
 * <li>update BeginDate/EndDate of every task</li>
 * </ul>
 * </p>
 * 
 * @author Michael Martin
 * @author Antonio Carrozzini
 * @version 1.0
 * 
 */
public class EndFrozen_BeginChange_UpdateTaskInPhase_Medium extends TestCase {

	/*
	 * Task		Begins 		Ends 		Predecessor Successor 	ChainingMode	Parent		task +2 days
	 * f1 		15.6.2009 	21.6.2009 	-	 		-		 	-	 			-			17.6.2009 - 23.6.2009
	 * t1		15.6.2009 	17.6.2009 	-			t2			ASAP 			f1			17.6.2009 - 19.6.2009
	 * t2		18.6.2009 	21.6.2009 	-			-			ASAP 			f1			20.6.2009 - 23.6.2009
	 * t3		16.6.2009 	20.6.2009 	-			-			Manual 			f1			18.6.2009 - 22.6.2009
	 */

	private Map<Integer, Object> map = null;
	private Logger log = Logger.getLogger("console");
	private DateFormat df = DateFormat.getInstance();
	private Task f1 = null;
	private TaskManager dateManager = new TaskManager();
	private static final long ADDED_DAYS = 2;

	protected void setUp() throws Exception {
		df = new SimpleDateFormat("dd.MM.yyyy");

		this.f1 = TaskFactory.getInstance();
		this.f1.setName("f1");
		this.f1.setType(Task.PHASE);

		Task t1 = TaskFactory.getInstance();
		t1.setName("t1");
		t1.setBeginDate(df.parse("15.6.2009"));
		t1.setEndDate(df.parse("17.6.2009"));
		t1.setDuration(48);
		t1.setState(new StateEndFrozenASAP(t1.getState().getDurationModeState()));

		Task t2 = TaskFactory.getInstance();
		t2.setName("t2");
		t2.setBeginDate(df.parse("18.6.2009"));
		t2.setEndDate(df.parse("21.6.2009"));
		t2.setDuration(72);
		t2.setState(new StateEndFrozenASAP(t2.getState().getDurationModeState()));

		Task t3 = TaskFactory.getInstance();
		t3.setName("t3");
		t3.setBeginDate(df.parse("16.6.2009"));
		t3.setEndDate(df.parse("20.6.2009"));
		t3.setDuration(96);
		t3.setState(new StateEndFrozenSPEC(t3.getState().getDurationModeState()));

		this.f1.addChild(t1);
		this.f1.addChild(t2);
		this.f1.addChild(t3);

		t1.addSuccessor(t2);

		super.setUp();
	}

	public void testReturnedListNotNull() {
		System.out.println("");
		log.debug(" === testReturnedListNotNull");

		Date newBeginDate = new Date(this.f1.getBeginDate().getTime() + (ADDED_DAYS * TimeConstants.DAY_IN_MILLIS));
		log.debug("new BeginDate = " + df.format(newBeginDate));

		this.map = new HashMap<Integer, Object>();
		this.map.put(NotificationsConstants.TASKMANAGER_ACTION_beginDate, newBeginDate);
		this.map.put(NotificationsConstants.TASKMANAGER_BEAN, this.f1);
		this.map.put(NotificationsConstants.TASKMANAGER_SENDER, null);

		log.debug("call TaskManager...");
		try {
			assertNotNull("Updated bean list isn't null", dateManager.manageDates(map));

		} catch (DateManagerException e) {
			fail(e.getMessage());

		}

	}

	public void testReturnedListSizeIsOk() {
		System.out.println("");
		log.debug(" === testReturnedListSizeIsOk");

		Date newBeginDate = new Date(this.f1.getBeginDate().getTime() + (ADDED_DAYS * TimeConstants.DAY_IN_MILLIS));
		log.debug("new BeginDate = " + df.format(newBeginDate));

		this.map = new HashMap<Integer, Object>();
		this.map.put(NotificationsConstants.TASKMANAGER_ACTION_beginDate, newBeginDate);
		this.map.put(NotificationsConstants.TASKMANAGER_BEAN, this.f1);
		this.map.put(NotificationsConstants.TASKMANAGER_SENDER, null);

		log.debug("call dateManager...");
		List<Task> updatedBeans = null;
		try {
			updatedBeans = dateManager.manageDates(this.map);

		} catch (DateManagerException e) {
			fail(e.getMessage());

		}
		assertEquals("Updated bean list size = 4", 4, updatedBeans.size());

	}

	public void testReturnedDatesAreOk() {
		System.out.println("");
		log.debug(" === testReturnedDatesAreOk");

		Date newBeginDate = new Date(this.f1.getBeginDate().getTime() + (ADDED_DAYS * TimeConstants.DAY_IN_MILLIS));
		log.debug("new BeginDate = " + df.format(newBeginDate));

		this.map = new HashMap<Integer, Object>();
		this.map.put(NotificationsConstants.TASKMANAGER_ACTION_beginDate, newBeginDate);
		this.map.put(NotificationsConstants.TASKMANAGER_BEAN, this.f1);
		this.map.put(NotificationsConstants.TASKMANAGER_SENDER, null);

		log.debug("call dateManager...");
		List<Task> updatedBeans = null;
		try {
			updatedBeans = dateManager .manageDates(this.map);

		} catch (DateManagerException e) {
			fail(e.getMessage());

		}

		for (Task updatedBean : updatedBeans) {
			log.debug(updatedBean.getName() + " \t updated with BeginDate = " + df.format(updatedBean.getBeginDate()) + " , EndDate = "
					+ df.format(updatedBean.getEndDate()));
			try {
				if (updatedBean.getName().equalsIgnoreCase("f1")) {
					assertEquals("check task BeginDate", df.parseObject("17.6.2009"), updatedBean.getBeginDate());
					assertEquals("check task EndDate", df.parseObject("23.6.2009"), updatedBean.getEndDate());
				}
				if (updatedBean.getName().equalsIgnoreCase("t1")) {
					assertEquals("check task BeginDate", df.parseObject("17.6.2009"), updatedBean.getBeginDate());
					assertEquals("check task EndDate", df.parseObject("19.6.2009"), updatedBean.getEndDate());
				}
				if (updatedBean.getName().equalsIgnoreCase("t2")) {
					assertEquals("check task BeginDate", df.parseObject("20.6.2009"), updatedBean.getBeginDate());
					assertEquals("check task EndDate", df.parseObject("23.6.2009"), updatedBean.getEndDate());
				}
				if (updatedBean.getName().equalsIgnoreCase("t3")) {
					assertEquals("check task BeginDate", df.parseObject("18.6.2009"), updatedBean.getBeginDate());
					assertEquals("check task EndDate", df.parseObject("22.6.2009"), updatedBean.getEndDate());
				}

			} catch (ParseException e) {
				fail(e.getMessage());

			}
		}
	}
}